using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;


namespace DT.Art.VFX.DTEditorGUI
{
    public enum ModuleKey
    {
        None = -1,
        MainTex = 0, YFPost = 1, HelpInfo, ColorTex, MaskTex = 4, DistortTex = 5, DissolveTex = 6,
        FNLMode = 7, GroundClipMode = 8, SprintMode = 9, CustomMode0 = 10,//Pass Work 暂时不用
        CustomMode1 = 11, CustomMode2 = 12, CustomEnd = 13
    }
    public static class DTVfxBaseProperty
    {
        public static readonly string m_ModuleKey = "_VfxMode";
        public static readonly string BlendMode = "_Blend";
        public static readonly string SrcBlend = "_SrcBlend";
        public static readonly string DstBlend = "_DstBlend";
        public static readonly string SrcBlendAlpha = "_SrcBlendAlpha";
        public static readonly string DstBlendAlpha = "_DstBlendAlpha";
        public static readonly string CullMode = "_Cull";
        public static readonly string AlphaClip = "_AlphaClip";
        public static readonly string AlphaToMask = "_AlphaToMask";
        public static readonly string ZTest = "_ZTest";
        public static readonly string ColorMask = "_ColorMask";
        public static readonly string GlobalAlpha = "_GlobalAlpha";
    }

    public static class DTPropKeyName
    {
        public const string enable = nameof(enable);
        public const string tex = nameof(tex);
        public const string texColor = nameof(texColor);

        public const string texST = nameof(texST);
        public const string texST1 = nameof(texST1);
        public const string texST2 = nameof(texST2);

        public const string uspeed = nameof(uspeed);
        public const string vspeed = nameof(vspeed);
        public const string matrix0 = nameof(matrix0);
        public const string matrix1 = nameof(matrix1);
        public const string ToolgetSw = nameof(ToolgetSw);
        public const string filterValue4 = nameof(filterValue4);
        public const string brightness = nameof(brightness);
        public const string alpha = nameof(alpha);


        public const string VfxModeProp = nameof(VfxModeProp);
        public const string blendModeProp = nameof(blendModeProp);
        public const string cullingProp = nameof(cullingProp);
        public const string zTestProp = nameof(zTestProp);
        public const string alphaToMaskProp = nameof(alphaToMaskProp);
        public const string colormask = nameof(colormask);
        public const string stencilCompProp = nameof(stencilCompProp);
        public const string stencilProp = nameof(stencilProp);
        public const string stencilOpProp = nameof(stencilOpProp);
        public const string stencilWriteMaskProp = nameof(stencilWriteMaskProp);
        public const string stencilReadMaskProp = nameof(stencilReadMaskProp);
        public const string zWriteProp = nameof(zWriteProp);
    }
    public static class DTFilteKeyName
    {
        public const string Enter = nameof(Enter);
        // public const string ModuleEnable = nameof(ModuleEnable);
        //-----------------------------------------------
        //UV按钮的滤镜键名 
        public const string Screen = nameof(Screen);
        public const string Polar = nameof(Polar);
        public const string Cx = nameof(Cx);
        public const string Cy = nameof(Cy);
        public const string Fx = nameof(Fx);
        public const string Fy = nameof(Fy);
        public const string Fill = nameof(Fill);
        // public const string key2 = nameof(key2);
        // public const string key3 = nameof(key3);
        // public const string key4 = nameof(key4);
        // public const string key5 = nameof(key5);
        // public const string key6 = nameof(key6);
        // public const string key7 = nameof(key7);
        // public const string key8 = nameof(key8);
        // public const string key9 = nameof(key9);
        public const string Frame = nameof(Frame);
        public const string Distort = nameof(Distort);

        //-----------------------------------------------
        public const string Umode = nameof(Umode);
        public const string Vmode = nameof(Vmode);
        // }
        // public static class DTColFilteKeyName
        // {
        //-----------------------------------------------
        //Color的滤镜键名
        public const string ColorBlend = nameof(ColorBlend);
        public const string AlphaBlend = nameof(AlphaBlend);
        public const string OnlyChannleAlp = nameof(OnlyChannleAlp);

        public const string Invert = nameof(Invert);
        public const string Gray = nameof(Gray);

        //-----------------------------------------------

    }
    [Flags]
    internal enum dtColorMask
    {
        None = 0,
        R = 1 << 3,
        G = 1 << 2,
        B = 1 << 1,
        A = 1 << 0,
        RGBA = ~0
    }

    /// <summary>
    /// The available color modes.
    /// Controls how the Particle color and the Material color blend together.
    /// </summary>
    internal enum ColorMode
    {
        Normal,
        /// <summary>
        /// Use this to select multiply mode.
        /// </summary>
        Multiply,
        /// <summary>
        /// Use this to select additive mode.
        /// </summary>
        Additive,
        /// <summary>
        /// Use this to select subtractive mode.
        /// </summary>
        Subtractive,
        /// <summary>
        /// Use this to select overlay mode.
        /// </summary>
        Overlay,
        /// <summary>
        /// Use this to select color mode.
        /// </summary>
        Color,
        /// <summary>
        /// Use this to select difference mode.
        /// </summary>
        Difference
    }

    public class DTGUIBitDate
    {
        public string Funkey = "";
        public string DisplayName = "";
        public bool IsCAddFilter = false;
        public Dictionary<string, MaterialProperty> Propertykeys = new Dictionary<string, MaterialProperty>();
        public List<string> UVBTNS = new List<string>();
        public List<string> ColorBTNS = new List<string>();
        public Dictionary<string, Bitkey> bitkeys = new Dictionary<string, Bitkey>();

        HashSet<MaterialProperty> handles = new HashSet<MaterialProperty>();

        public DTGUIBitDate(string funkey, string displayName)
        {
            Propertykeys.Clear();
            UVBTNS.Clear();
            ColorBTNS.Clear();
            bitkeys.Clear();
            Funkey = funkey;
            DisplayName = displayName;
            Propertykeys = new Dictionary<string, MaterialProperty>()
            {
                {DTPropKeyName.enable, null},    //bool
                {DTPropKeyName.tex, null},       //tex
                {DTPropKeyName.texColor, null},  //color
                {DTPropKeyName.texST, null},     //v4
                {DTPropKeyName.texST1, null},    //v4
                {DTPropKeyName.texST2, null},    //v4
                {DTPropKeyName.uspeed, null},    //float
                {DTPropKeyName.vspeed, null},    //float
                {DTPropKeyName.matrix0, null},   //v4
                {DTPropKeyName.matrix1, null},   //v4
                {DTPropKeyName.ToolgetSw, null}, //v4

                {DTPropKeyName.filterValue4, null},//V4 

                {DTPropKeyName.brightness, null},//float
                {DTPropKeyName.alpha, null},//float
                
            };
            bitkeys = new Dictionary<string, Bitkey>()
            {
                // {DTFilteKeyName.ModuleEnable, new Bitkey()},
                {DTFilteKeyName.Umode, new Bitkey()},
                {DTFilteKeyName.Vmode, new Bitkey()},

                {DTFilteKeyName.Screen, new Bitkey("", 0, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("屏", "屏幕UV")) },
                {DTFilteKeyName.Polar, new Bitkey("", 1, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("极", "极坐标")) },
                {DTFilteKeyName.Cx, new Bitkey("", 2, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("Cx", "Clamp UV U限制到0-1")) },
                {DTFilteKeyName.Cy, new Bitkey("", 3, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("Cy", "Clamp UV V限制到0-1")) },
                {DTFilteKeyName.Fx, new Bitkey("", 4, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("Fx", "Flip UV U翻转")) },
                {DTFilteKeyName.Fy, new Bitkey("", 5, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("Fy", "Flip UV V翻转")) },
                {DTFilteKeyName.Fill, new Bitkey("", 6, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("填", "按A通道填充白色")) },
                {DTFilteKeyName.Frame, new Bitkey("", 14, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("序", "序列帧")) },
                {DTFilteKeyName.Distort, new Bitkey("", 13, 1, ChannelMode.y, true, DTGUIEx.DTGetContent("扰", "扰动UV开关")) },

                {DTFilteKeyName.ColorBlend , new Bitkey("", 0, 4, ChannelMode.z, true, DTGUIEx.DTGetContent("Bc", "颜色混合")) },
                {DTFilteKeyName.AlphaBlend , new Bitkey("", 4, 4, ChannelMode.z, true, DTGUIEx.DTGetContent("Ba", "A通道混合")) },
                {DTFilteKeyName.Invert, new Bitkey("", 8, 1, ChannelMode.z, true, DTGUIEx.DTGetContent("反", "反转")) },
                {DTFilteKeyName.Gray, new Bitkey("", 9, 1, ChannelMode.z, true, DTGUIEx.DTGetContent("灰", "灰度")) },
                {DTFilteKeyName.OnlyChannleAlp, new Bitkey("", 10, 4, ChannelMode.z, true, DTGUIEx.DTGetContent("通", "显示RGBA的灰度通道")) },

            };
        }

        public int GetUVModeKey(string key)
        {
            if (bitkeys.ContainsKey(key))
            {
                return bitkeys[key].GetValue(Propertykeys);
            }
            return 0;
        }
        public bool GetBTNout(string key)
        {
            if (bitkeys.ContainsKey(key))
            {
                return bitkeys[key].GetValue(Propertykeys) > 0;
            }
            return false;
        }


        public void SetBitProp(string keyname, string propname, int pos = -1, int len = 0, ChannelMode channelMode = ChannelMode.none)
        {
            if (bitkeys.ContainsKey(keyname))
            {
                Bitkey tmp = bitkeys[keyname];
                tmp.PropKey = propname;
                tmp.isView = true;
                tmp.index = pos;
                tmp.len = len;
                tmp.mode = channelMode;
                bitkeys[keyname] = tmp;
            }
        }
        public void SetBitView(string keyname, bool isv)
        {
            if (bitkeys.ContainsKey(keyname))
            {
                Bitkey tmp = bitkeys[keyname];
                tmp.isView = isv;
                bitkeys[keyname] = tmp;
            }
        }

        public void SetBitLable(string keyname, GUIContent lable)
        {
            if (bitkeys.ContainsKey(keyname))
            {
                Bitkey tmp = bitkeys[keyname];
                tmp.lable = lable;
                bitkeys[keyname] = tmp;
            }
        }
        public void InitProperty()
        {
            foreach (var item in Propertykeys)
            {
                if (item.Value != null)
                {
                    handles.Add(item.Value);
                }
            }
        }
        public void MEBeginProperty()
        {
            foreach (var item in handles)
            {
                if (item != null)
                    MaterialEditor.BeginProperty(item);
            }
        }
        public void MEEndProperty()
        {
            foreach (var item in handles)
            {
                if (item != null)
                    MaterialEditor.EndProperty();
            }
        }

        public MaterialProperty GetProp(string key)
        {
            if (Propertykeys.ContainsKey(key)) return Propertykeys[key];
            return GetBitkey(key).GetProp(Propertykeys);
        }

        public string GetPropName(string key)
        {
            MaterialProperty prop = GetProp(key);
            if (prop != null) return prop.name;
            return "";
        }

        public string GetPropDispName(string key)
        {
            MaterialProperty prop = GetProp(key);
            if (prop != null) return prop.displayName;
            return "";
        }

        public Bitkey GetBitkey(string key)
        {
            if (bitkeys.ContainsKey(key)) return bitkeys[key];
            return new Bitkey();
        }


    }
}
